package db

import (
	"fmt"
	"gdmin/config"
	"gdmin/global"
	"gdmin/servlet"
	"gdmin/utils"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"math"
)

func Init(config config.Db) {

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local", config.User, config.Password, config.Host, config.Port, config.Database)

	hlog.Info("数据库地址  ", dsn)
	db, err := gorm.Open(mysql.New(mysql.Config{
		DriverName: "mysql",

		DSN: dsn,

		DefaultStringSize:         256,
		DisableDatetimePrecision:  true,
		DontSupportRenameIndex:    true,
		DontSupportRenameColumn:   true,
		SkipInitializeWithVersion: false,
	}), &gorm.Config{
		//Logger: logger.Default.LogMode(logger.Info),
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 使用单数表名
		},
	})

	if err != nil {
		panic("连接数据库失败, middleware=" + err.Error())
	}
	hlog.Info("连接数据库成功")
	err = db.Callback().Create().Register("gorm:before_create", beforeSaveCallback)
	err = db.Callback().Delete().Register("gorm:before_delete", beforeUpdateCallback)
	err = db.Callback().Update().Register("gorm:before_update", beforeUpdateCallback)
	if err != nil {
		return
	}
	global.DB = db

}

func CommonPage(page *servlet.Pagination, value interface{}, db *gorm.DB) *servlet.Pagination {

	db.Scopes(paginate(value, page, db)).Find(value)

	page.Records = value
	return page
}

func paginate(value interface{}, pagination *servlet.Pagination, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	var totalRows int64
	db.Model(value).Count(&totalRows)
	pagination.Total = totalRows
	totalPages := int(math.Ceil(float64(totalRows) / float64(pagination.PageSize)))
	pagination.TotalPages = totalPages
	return func(db *gorm.DB) *gorm.DB {
		return db.Offset(pagination.GetOffset()).Limit(pagination.GetLimit()).Order(pagination.GetSort())
	}
}

func beforeSaveCallback(tx *gorm.DB) {
	tx.Statement.SetColumn("CreateUserId", utils.GetThreadUserId())
	tx.Statement.SetColumn("UpdateUserId", utils.GetThreadUserId())
}

func beforeUpdateCallback(tx *gorm.DB) {
	tx.Statement.SetColumn("UpdateUserId", utils.GetThreadUserId())
}
